﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace SilverlightControlStyle.Controls
{
    /// <summary>
    /// 自定义日期控件
    /// </summary>
    public class CustomDatePicker : Control
    {
        #region 常量

        private const string DefaultDateFormat = "yyyy.MM.dd";
        #endregion

        #region 字段
        private ToggleButton _tglButton;
        private Popup _calPopup;
        private Calendar _calendar;

        private string _dateFormat;
        #endregion

        #region
        /// <summary>
        /// 日期显示格式
        /// </summary>
        public string DateFormat
        {
            get { return _dateFormat; }
            set
            {
                _dateFormat = value;
                DisplayDate = string.IsNullOrWhiteSpace(value)
                    ? DateTime.Now.ToString(DefaultDateFormat) : DateTime.Now.ToString(value);
            }
        }
        /// <summary>
        /// 表示显示年份、月份、日期
        /// </summary>
        public CalendarMode DateMode { get; set; }
        #endregion

        #region 构造函数
        public CustomDatePicker()
            : this(DefaultDateFormat, CalendarMode.Month)
        { }

        public CustomDatePicker(string pDateFormat, CalendarMode pDateMode)
        {
            DefaultStyleKey = typeof(CustomDatePicker);

            DateFormat = pDateFormat;
            DateMode = pDateMode;
            SelectedDate = DateTime.Now;
        }
        #endregion

        #region 依赖属性

        /// <summary>
        /// 是否只读
        /// </summary>
        public bool IsReadOnly
        {
            get { return (bool)GetValue(IsReadOnlyProperty); }
            set { SetValue(IsReadOnlyProperty, value); }
        }

        /// <summary>
        /// 当前日期
        /// </summary>
        public DateTime SelectedDate
        {
            get { return (DateTime)GetValue(SelectedDateProperty); }
            set
            {
                SetValue(SelectedDateProperty, value);

                DisplayDate = string.IsNullOrWhiteSpace(DateFormat)
                    ? value.ToString("yyyy-MM-dd") : value.ToString(DateFormat);
            }
        }

        /// <summary>
        /// 显示日期
        /// </summary>
        public string DisplayDate
        {
            get { return (string)GetValue(DisplayDateProperty); }
            set { SetValue(DisplayDateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DisplayDate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DisplayDateProperty =
            DependencyProperty.Register("DisplayDate", typeof(string), typeof(CustomDatePicker), null);
        // Using a DependencyProperty as the backing store for SelectedDate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedDateProperty =
            DependencyProperty.Register("SelectedDate", typeof(DateTime), typeof(CustomDatePicker), new PropertyMetadata(DateTime.Now));
        // Using a DependencyProperty as the backing store for IsReadOnly.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(CustomDatePicker), new PropertyMetadata(true));
        #endregion

        #region 重写 私有方法
        /// <summary>
        /// 从模板获取控件
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _tglButton = GetTemplateChild("XToggleButton") as ToggleButton;
            _calPopup = GetTemplateChild("XCalendarPopup") as Popup;
            _calendar = GetTemplateChild("XCalendar") as Calendar;

            if (_tglButton != null)
                _tglButton.Click += OntglButton_Click;

            if (_calendar != null)
            {
                if (DateMode == CalendarMode.Month)
                    _calendar.SelectedDatesChanged += Oncalendar_SelectedDatesChanged;
                else
                    _calendar.DisplayModeChanged += Oncalendar_DisplayModeChanged;
            }
        }

        private void Oncalendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_calendar.SelectedDate != null)
                SelectedDate = _calendar.SelectedDate.Value;

            _calPopup.IsOpen = false;
            _tglButton.IsChecked = false;
        }

        private void Oncalendar_DisplayModeChanged(object sender, CalendarModeChangedEventArgs e)
        {
            SelectedDate = _calendar.DisplayDate;

            //仅选择月，Calendar关闭情况判断
            if (e.NewMode.Equals(CalendarMode.Month))
            {
                _calPopup.IsOpen = false;
                _tglButton.IsChecked = false;
            }

            //只选择年，Calendar 关闭情况判断
            if (DateMode == CalendarMode.Decade && e.NewMode == CalendarMode.Year && e.OldMode == DateMode)
            {
                _calPopup.IsOpen = false;
                _tglButton.IsChecked = false;
            }
        }

        /// <summary>
        /// 选择按钮显示/隐藏日历控件
        /// </summary>
        private void OntglButton_Click(object sender, RoutedEventArgs e)
        {
            var tglButton = sender as ToggleButton;
            if (tglButton != null && tglButton.IsChecked != null)
                _calPopup.IsOpen = tglButton.IsChecked.Value;

            _calendar.DisplayMode = DateMode;
        }
        #endregion
    }
}
